package com.huidu.bitrade.service;

import com.alibaba.fastjson2.JSON;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.huidu.bitrade.constant.TransactionType;
import com.huidu.bitrade.entity.Member;
import com.huidu.bitrade.entity.MemberLoan;
import com.huidu.bitrade.entity.MemberTransaction;
import com.huidu.bitrade.entity.MemberWallet;
import com.huidu.bitrade.enums.MemberLoanStatus;
import com.huidu.bitrade.mapper.MemberLoanMapper;
import com.huidu.bitrade.query.MemberLoanPageQuery;
import com.huidu.bitrade.vo.MemberAccountVO;
import com.huidu.bitrade.vo.MemberLoanVO;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.Assert;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.util.Date;
import java.util.List;
import java.util.Objects;

@Service
@RequiredArgsConstructor(onConstructor_ = @Autowired)
public class MemberLoanService extends ServiceImpl<MemberLoanMapper, MemberLoan> implements AuditService<MemberLoan> {

    private final MemberLoanMapper memberLoanMapper;
    private final MemberWalletService memberWalletService;
    private final MemberService memberService;
    private final MemberTransactionService transactionService;

    public Page<MemberLoanVO> list(IPage page, Long memberId, Integer type){
        return memberLoanMapper.selectVoList(page,memberId,type);
    }

    /**
     * 提交变现申请
     * @param memberLoan
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public boolean apply(MemberLoan memberLoan) {
        Member member = memberService.findOne(memberLoan.getMemberId());
        MemberAccountVO memberAccountVO = new MemberAccountVO();
        memberAccountVO.setRealName(member.getRealName());
        switch (memberLoan.getPayType()){
            case 1:
                memberAccountVO.setAlipay(member.getAlipay());
                break;
            case 2:
                memberAccountVO.setWechatPay(member.getWechatPay());
                break;
            case 3:
                memberAccountVO.setBankInfo(member.getBankInfo());
                break;
        }
        Long memberId = memberLoan.getMemberId();
        MemberWallet memberWallet = memberWalletService.findByCoinUnitAndMemberId(memberLoan.getBaseCoinSymbol(), memberId);
        Assert.isTrue(Objects.nonNull(memberWallet),"用户钱包不存在");

        BigDecimal number = memberLoan.getNumber();
        Assert.isTrue(memberWallet.getBalance().compareTo(number) >0,"钱包余额不足");
        //减少钱包余额
        memberWalletService.deductBalance(memberWallet, number);
        //添加流水记录
        MemberTransaction transaction = new MemberTransaction();
        transaction.setAmount(number);
        transaction.setSymbol(memberLoan.getBaseCoinSymbol());
        transaction.setMemberId(memberId);
        transaction.setType(TransactionType.PLEDGE_LOAN_OUT);
        transaction.setCreateTime(new Date());
        transactionService.save(transaction);
        memberLoan.setMemberId(memberId);
        memberLoan.setPayInfo(JSON.toJSONString(memberAccountVO));
        memberLoan.setCreateUser(memberId);
        return memberLoanMapper.insert(memberLoan) > 0;
    }

    /**
     * 通过变现申请
     * @param memberLoan 数据ID
     * @return
     */
    @Override
    public boolean audit(MemberLoan memberLoan) {
        ZoneId zone = ZoneId.systemDefault();
        long endDate = LocalDateTime.now().plusMonths(3).atZone(zone).toInstant().toEpochMilli();
        memberLoan.setEndDate(endDate);
        memberLoan.setStatus(MemberLoanStatus.WAIT_REDEMPTION);
        return memberLoanMapper.updateById(memberLoan) > 0;
    }

    /**
     * 拒绝变现申请
     * @param memberLoan
     * @param description
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean reject(MemberLoan memberLoan, String description) {
        addWallet(memberLoan);
        memberLoan.setStatus(MemberLoanStatus.REJECT);
        memberLoan.setReason(description);
        return memberLoanMapper.updateById(memberLoan) > 0;
    }

    /**
     * 申请赎回
     * @param id
     * @return
     */
//    public boolean redemption(Long id){
//        MemberLoan memberLoan = memberLoanMapper.selectById(id);
//        Assert.isTrue(Objects.nonNull(memberLoan),"信息不存在");
//        Assert.isTrue(memberLoan.getStatus().equals(2) || memberLoan.getStatus().equals(3),"当前状态不可赎回");
//        LocalDateTime endDate = LocalDateTimeUtil.of(memberLoan.getEndDate());
//        Assert.isTrue(endDate.isBefore(LocalDateTime.now()),"未满三个月不可赎回");
//        memberLoan.setStatus(MemberLoanStatus.APPLE_REDEMPTION);
//        memberLoan.setUpdateUser(memberLoan.getMemberId());
//        return memberLoanMapper.updateById(memberLoan) > 0;
//    }

    /**
     * 审核赎回申请
     * @param memberLoan
     * @return
     */
    public boolean redemptionAudit(MemberLoan memberLoan){
        memberLoan.setStatus(MemberLoanStatus.REDEMPTION_OVER);
        addWallet(memberLoan);
        return memberLoanMapper.updateById(memberLoan) > 0;
    }

    private void addWallet(MemberLoan memberLoan){
        MemberWallet memberWallet = memberWalletService.findByCoinUnitAndMemberId(memberLoan.getBaseCoinSymbol(), memberLoan.getMemberId());
        Assert.isTrue(Objects.nonNull(memberWallet),"用户钱包不存在");
        //增加钱包余额
        memberWalletService.increaseBalance(memberWallet.getId(), memberLoan.getNumber());
        //添加流水记录
        MemberTransaction transaction = new MemberTransaction();
        transaction.setAmount(memberLoan.getNumber());
        transaction.setSymbol(memberLoan.getBaseCoinSymbol());
        transaction.setMemberId(memberLoan.getMemberId());
        transaction.setType(TransactionType.PLEDGE_LOAN_IN);
        transaction.setCreateTime(new Date());
        transactionService.save(transaction);
    }

    public IPage<MemberLoanVO> pageList(IPage page, MemberLoanPageQuery mpPageQuery){
        return page.setRecords(memberLoanMapper.pageList(page,mpPageQuery));
    }


    /**
     * 查询正在进行中的变现订单
     * @param memberId
     * @return
     */
    public List<MemberLoan> selectUnderway(Long memberId){
        return memberLoanMapper.selectUnderway(memberId);
    }

}
